home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
16bpp_48bit
/
c
/
burkes
next >
Wrap
Text File
|
1995-10-16
|
4KB
|
141 lines
/* burkes.c
* AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
* LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
*
* filter: * 4 2
* 1 2 4 2 1 (1/16)
*/
#include "internal.h"
#include <assert.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* calloc() */
#include "OS:hourglass.h"
#include "OS:macros.h"
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern bool process_gif_16bpp_burkes_48bit(
const process_gif *p) {
byte *rove;
int width, height;
int x, y;
const os_colour *palette;
int line_length;
int *buffer, *this_row, *next_row;
int buffer_width;
int red, grn, blu;
bits t;
int error_red, error_grn, error_blu;
int temp_red, temp_grn, temp_blu;
rgbtupleout error;
rgbtupleout_fn fn;
assert(p);
assert(p->pixel_width > 0);
assert(p->pixel_height > 0);
assert(p->in_palette.colours);
assert(p->fn);
/*
* burkes requires storing error info for two pixels to right and two pixels to left
* so we will just allocate two extra columns for each row and not do any edge checks
* each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
*/
buffer_width = (2 + p->pixel_width + 2) * 3;
buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
if (!buffer) {
/*
* oh dear
*/
return TRUE;
}
/*
* note we pre-load values from the process_gif array
* because it considerably helps the compiler produce better code
*/
rove = p->buffer;
width = p->pixel_width;
height = p->pixel_height;
palette = p->in_palette.colours;
line_length = p->line_length;
fn = p->fn;
for (y= height; (y > 0); y--) {
if ((y & 7) == 0) {
xhourglass_percentage((y * 100) / height);
}
this_row = buffer + (buffer_width * ((y + 2) % 2)) + 2*3;
next_row = buffer + (buffer_width * ((y + 1) % 2)) + 2*3;
/* bottom row has no errors */
memset(next_row, 0, sizeof(*next_row) * (buffer_width - 2*3));
/*
* note that just because we are actually scanning/outputting right to left
* doesn't matter as far as burkes is concerned
* although it might help if we could ``snake''
*/
for (x= width - 1; (x >= 0); x--) {
INPUT;
red += *this_row++; /* add in errors from all rows */
grn += *this_row++;
blu += *this_row++;
PROCESS;
temp_red = (red * 4) / 16; error_red = red - (2 * temp_red);
temp_grn = (grn * 4) / 16; error_grn = grn - (2 * temp_grn);
temp_blu = (blu * 4) / 16; error_blu = blu - (2 * temp_blu);
this_row[ 0] += temp_red; /* this[ 1] += 4/16 */
this_row[ 1] += temp_grn;
this_row[ 2] += temp_blu;
next_row[ 0] += temp_red; /* next[ 0] += 4/16 */
next_row[ 1] += temp_grn;
next_row[ 2] += temp_blu;
temp_red >>= 1; error_red -= 3 * temp_red;
temp_grn >>= 1; error_grn -= 3 * temp_grn;
temp_blu >>= 1; error_blu -= 3 * temp_blu;
this_row[ 3] += temp_red; /* this[ 2] += 2/16 */
this_row[ 4] += temp_grn;
this_row[ 5] += temp_blu;
next_row[ 3] += temp_red; /* next[ 1] += 2/16 */
next_row[ 4] += temp_grn;
next_row[ 5] += temp_blu;
next_row[-3] += temp_red; /* next[-1] += 2/16 */
next_row[-2] += temp_grn;
next_row[-1] += temp_blu;
temp_red += temp_red >> 1; error_red -= temp_red;
temp_grn += temp_grn >> 1; error_grn -= temp_grn;
temp_blu += temp_blu >> 1; error_blu -= temp_blu;
next_row[-6] += temp_red; /* next[-2] += 1/16 */
next_row[-5] += temp_grn;
next_row[-4] += temp_blu;
next_row[ 6] += error_red; /* next[ 2] += 1/16 */
next_row[ 7] += error_grn;
next_row[ 8] += error_blu;
next_row += 3; /* adjust next_row pointer */
}
rove += line_length;
}
free(buffer);
return FALSE;
}